super 关键字

继承中的 super 关键字

在 Java 中,super 关键字用于表示当前对象的父类。它可以用来调用父类的构造函数、访问父类的字段以及调用父类的方法。super 主要应用在以下几个场景中:

  1. 调用父类的构造函数:当子类构造函数没有显式调用父类构造函数时,Java 会自动调用父类的无参构造函数。使用 super() 可以显式调用父类的构造函数,特别是在父类没有无参构造函数时。
  2. 访问父类的字段:当子类有与父类相同名称的字段时,super 可以用来访问父类的字段。
  3. 调用父类的方法:如果子类重写了父类的方法,但在某些情况下仍然需要调用父类的方法,可以通过 super 来实现。

1. 调用父类的构造函数

在子类的构造函数中,如果希望显式调用父类的构造函数,可以使用 super()。如果没有显式调用,Java 会自动调用父类的无参构造函数。

  • 如果父类没有无参构造函数,或者需要调用父类的带参构造函数,则必须使用 super() 显式调用父类构造函数。
示例
class Animal {
    String name;

    // 父类带参构造函数
    public Animal(String name) {
        this.name = name;
    }

    public void eat() {
        System.out.println("This animal eats food.");
    }
}

class Dog extends Animal {
    // 子类构造函数显式调用父类构造函数
    public Dog(String name) {
        super(name);  // 调用父类的构造函数
    }

    @Override
    public void eat() {
        System.out.println("This dog eats meat.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy");
        System.out.println("Dog's name: " + dog.name);
        dog.eat();  // 调用重写的方法
    }
}

输出

Dog's name: Buddy
This dog eats meat.

在上面的代码中,Dog 类通过 super(name) 显式调用了 Animal 类的带参构造函数,并且传递了 name 参数。


2. 访问父类的字段

如果子类有与父类同名的字段,可以使用 super 来访问父类的字段,避免和子类的字段产生冲突。

示例

class Animal {
    String name = "Animal";

    public void display() {
        System.out.println("This is an animal.");
    }
}

class Dog extends Animal {
    String name = "Dog";

    public void show() {
        System.out.println("Dog name: " + name);          // 访问子类字段
        System.out.println("Parent name: " + super.name); // 访问父类字段
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.show();
    }
}

输出

Dog name: Dog
Parent name: Animal

在这个例子中,Dog 类重写了父类 Animalname 字段。通过 super.name,我们访问了父类的 name 字段,而通过 name,我们访问了子类的 name 字段。


3. 调用父类的方法

如果子类重写了父类的方法,但希望在子类中仍然调用父类的实现,可以使用 super 关键字。

示例

class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound.");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        super.makeSound();  // 调用父类的 makeSound 方法
        System.out.println("Dog barks.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound();
    }
}

输出

Animal makes a sound.
Dog barks.

在这个例子中,Dog 类重写了 makeSound() 方法,在重写的方法中调用了父类 AnimalmakeSound() 方法,显示了父类的输出后再输出子类的内容。


总结

  • super():用于调用父类的构造函数,通常在子类的构造函数中显式调用父类的构造函数。
  • super.field:用于访问父类的字段,当子类和父类有相同的字段时,可以使用 super 来区分。
  • super.method():用于调用父类的方法,特别是在子类重写父类方法的情况下,可以使用 super 调用父类的方法。

通过 super 关键字,Java 实现了子类与父类之间的交互,使得子类能够继承父类的功能,同时在需要时对父类的行为进行修改或扩展。

super深层剖析

相关笔记

super 与 this 的使用规则速成见 super与this关键字(04-关键字组);本篇及 super深层剖析 负责挖底层。


⬅️ 抽象类与接口的结合 🏠 00-Java ➡️ super深层剖析